package com.example.springboot.services.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.springboot.domain.DbBackup;
import com.example.springboot.domain.PageBean;
import com.example.springboot.mapper.DBMapper;
import com.example.springboot.services.DBService;
import com.example.springboot.utils.Security;
import com.example.springboot.utils.ThreadLocalUtil;
import com.example.springboot.utils.ZIpUtil;
import com.example.springboot.vo.ResVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

@Slf4j
@Service
public class DBServiceImpl implements DBService {

    @Autowired
    DBMapper dbMapper;

    @Value("${spring.datasource.password}")
    private String password;

    @Value("${filePath}")
    String filePath;//源文件路径

    @Value("${dbData.dbName}")
    String dbName;//数据库名


    @Value("${zipPath}")
    String zipPath;//压缩文件路径

    @Override
    public  PageBean<DbBackup> searchRecord(Integer page, Integer pageSize, String name, Integer type, String createTime) {

        PageBean<DbBackup> dbBackupPageBean=new PageBean<>();
        //查询文件数据
//        Map<String,Object> selectMap = new HashMap<>();
//        selectMap.put("name",name);
//        selectMap.put("type",type);
//        selectMap.put("createTime",createTime);
        dbBackupPageBean.setData(dbMapper.searchRecord(page,pageSize,name,type,createTime));
        dbBackupPageBean.setTotal(dbMapper.searchRecordAll(name,type, createTime));

        return dbBackupPageBean;
    }

    @Override
    public  List<String> queryRecordByIdList(List<Integer> idList) {
        List<String> filePath=new ArrayList<>();
        List<DbBackup> list = dbMapper.queryRecordByIdList(idList);
        for (DbBackup dbBackup : list) {
            String[] strs= dbBackup.getPath().split("\\\\");
            String str="";
            if(strs.length>0) {
                str = strs[strs.length-1].split("\\.")[0];
            }
            filePath.add(str+".zip");
        }
        return filePath;

    }

    @Override
    public Boolean databasebackup(List<String> list) throws InterruptedException {
        //数据处理
        String fileName = dbName + new java.util.Date().getTime();
        List<String> sylist=dbMapper.queryTables();
        String listStr = " ";
        int i=0;//判断表是否都存在
        for (String s : list) {
            if(sylist.contains(s)){
                i++;
                listStr = listStr + s + " ";
            }
        }

        //sql文件备份
        if (i==sylist.size()){
            try {
                Process process = Runtime.getRuntime().exec(
                        "cmd  /c  mysqldump -uroot -p" +password + " --databases " + dbName + " > "
                                + filePath + "sql" + "/" + fileName
                                + ".sql");
                log.info("备份文件中");
                //数据库连接和密码均为root
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }
        else if(i!=0){
            try {
                Process process = Runtime.getRuntime().exec(
                        "cmd  /c  mysqldump -uroot -proot " + "--databases " + dbName + " --tables" + listStr + " > "
                                + filePath +"sql" + "/" + fileName
                                + ".sql");
                System.out.println("备份中");
                //数据库连接和密码均为root
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }
        else  return false;

        //文件压缩处理
        Thread.sleep(500);
        FileOutputStream fos;
        try {
            fos = new FileOutputStream(new File(zipPath+fileName+".zip"));
            String path2=filePath +"sql" + "/" + fileName+ ".sql";
            ZIpUtil.filetoZip(path2, fos);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        //文件加密
        try {
            Security.security(filePath +"sql" + "/" + fileName+ ".sql",filePath  + "/" + fileName+ ".sql");
        }catch (IOException e){
            e.printStackTrace();
        }

        File file =new File(filePath +"sql" + "/" + fileName+ ".sql");
        file.delete();

        //访问数据库
        DbBackup record=new DbBackup(fileName,filePath+fileName+".sql",1, ThreadLocalUtil.getName(), null,1);
        // DbBackup record = new DbBackup();
        int k=0;
        k=dbMapper.insert(record);
        if(k==0){
            return false;
        }

        return true;
    }

    /**
     * 查询数据库表
     * @return
     */
    @Override
    public List<String> queryTables() {
        List<String> list=dbMapper.queryTables();
        return list;
    }

    @Override
    public Boolean removeFile(List<Integer> idList) {
        File file=null;
        Integer integer=0;
        if(idList.size()!=0){
            List<DbBackup> list = dbMapper.queryRecordByIdList(idList);
            for (DbBackup dbBackup : list) {
                file=new File(dbBackup.getPath());
                file.delete();
            }
            integer = dbMapper.deleteBatchIds(idList);
        }
        if(integer!=0){
            return true;
        }
        return false;
    }

    @Override
    public Boolean rollBack(String id) {

        ReentrantLock reentrantLock = new ReentrantLock(true);
        reentrantLock.lock();
        try {

        } finally {
            reentrantLock.unlock();
        }

        synchronized (this) {

        }

        DbBackup dbBackup = dbMapper.selectById(id);

        //文件解密
        String tempPath = filePath +"sql"  + "\\temp.sql";
        try {
            Security.security(dbBackup.getPath(),tempPath);
        }catch (IOException e){
            e.printStackTrace();
        }

        try {
            Process process = Runtime.getRuntime().exec(
                    "cmd  /c  mysql -hlocalhost -uroot -p" + password +" "+ dbName +  " < "
                            + tempPath);
            log.info("数据库恢复");

            process.waitFor(3000, TimeUnit.MILLISECONDS);

            //数据库连接和密码均为root
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }

//        try {
//            Thread.sleep(500);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }

        File file =new File(tempPath);
        if (file.exists()){
            file.delete();
        }

        return true;
    }


}
